package modelo.obstaculos;

import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;

import modelo.enemigos.Enemigo;
import modelo.interfaces.Posicionable;
import modelo.mapa.Casillero;

import java.util.Observable;

public abstract class Obstaculo extends Observable implements Posicionable, Serializable {

	private Casillero casillero;
	private int costo;
	private LinkedList<Efecto> efectos;
	private ManejadorObstaculos manejador;


	public void setCasillero(Casillero casillero) {
		this.casillero = casillero;
		this.setChanged();
		this.notifyObservers();
	}

	public Casillero getCasillero() {
		return this.casillero;
	}

	public int getCosto() {
		return this.costo;
	}

	public void setCosto(int costo) {
		this.costo = costo;
	}


	public ManejadorObstaculos getManejador() {
		return this.manejador;
	}

	public void setManejador(ManejadorObstaculos manejador) {
		this.manejador = manejador;
	}

	public LinkedList<Efecto> getEfectos() {
		return this.efectos;
	}

	public void setEfectos(LinkedList<Efecto> efectos) {
		this.efectos = efectos;
	}

	protected abstract void Afectar(Enemigo enemigo);

	protected abstract void Desafectar(Efecto efecto);
	
	public abstract void RecrearVista();
	
	public void Actuar() {

		this.detectarEnemigos();
		this.actualizarEfectos();
	}

	private void detectarEnemigos() {
		Collection<Posicionable> enemigosDetectados = this.manejador.getMapa().elementosEnRango(this.casillero, 0);
		Iterator<Posicionable> iteradorEnemigos = enemigosDetectados.iterator();
		Object objeto;

		while (iteradorEnemigos.hasNext()) {
			objeto = iteradorEnemigos.next();

			if (objeto instanceof Enemigo) {
				Enemigo enemigo = (Enemigo) objeto; // (Enemigo)
													// iteradorEnemigos.next();
				if (!(enemigo.getVolar()))
					if (!(this.estaAfectado(enemigo)))
						this.Afectar(enemigo);
				
				}

		}

	}

	private void actualizarEfectos() {
		Iterator<Efecto> iteradorEfectos = this.efectos.iterator();
		LinkedList<Efecto> nuevaLista = new LinkedList<Efecto>();
		
		while (iteradorEfectos.hasNext()) {
			Efecto efecto = (Efecto) iteradorEfectos.next();
			efecto.setDuracion(efecto.getDuracion() - 1);
			if (efecto.getDuracion() <= 0){
				this.Desafectar(efecto);
				}
			else
				{
				nuevaLista.add(efecto);
				}
		}
		efectos= nuevaLista;
	}

	public void Vaciar() {
		this.efectos.clear();
	}

	private boolean estaAfectado(Enemigo enemigo) {

		Iterator<Efecto> iteradorEfectos = this.efectos.iterator();
		boolean encontrado = false;

		while (iteradorEfectos.hasNext()) {
			Efecto efecto = (Efecto) iteradorEfectos.next();
			if (efecto.getEnemigo().equals(enemigo)) {
				encontrado = true;
			}
		}

		return encontrado;
	}

}
